package com.cskaoyan.config.shiro;

import com.cskaoyan.bean.po.*;
import com.cskaoyan.mapper.MarketAdminMapper;
import com.cskaoyan.mapper.MarketPermissionMapper;
import com.cskaoyan.mapper.MarketRoleMapper;
import com.cskaoyan.mapper.MarketUserMapper;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * ClassName: CustomRealm
 * Description:
 * date: 2022/6/6 19:25
 *
 * @author bruce
 * @since JDK 8
 */
@Component
public class CustomRealm extends AuthorizingRealm {

    @Autowired
    MarketAdminMapper adminMapper;

    @Autowired
    MarketUserMapper userMapper;

    @Autowired
    MarketPermissionMapper marketPermissionMapper;

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 根据subject.login传入的authenticationToken获得认证信息
        // 根据token中传入的username来查询该用户在系统中正确的密码（Credentials）
        String type = ((MallToken) authenticationToken).getType();
        String username = (String) authenticationToken.getPrincipal();
        // 能否从数据库里查出该用户名所对应的密码呢


        if ("admin".equals(type)) {
            // admin的credentials的查询
            MarketAdminExample example = new MarketAdminExample();
            example.createCriteria().andUsernameEqualTo(username);
            List<MarketAdmin> marketAdmins = adminMapper.selectByExample(example);
            if (marketAdmins != null && marketAdmins.size() == 1) {
                MarketAdmin marketAdmin = marketAdmins.get(0);
                String credentials = marketAdmin.getPassword(); // 正确的密码
                // 第一个参数：principal信息 → 放入啥信息都行，取决于开发人员 → 你放入的是什么信息，你取出的就是什么信息
                return new SimpleAuthenticationInfo(marketAdmin, credentials, this.getName());
            }
        }
        if ("wx".equals(type)) {
            // wx的credentials的查询
            MarketUserExample example = new MarketUserExample();
            MarketUserExample.Criteria criteria = example.createCriteria();
            criteria.andUsernameEqualTo(username);
            List<MarketUser> marketUsers = userMapper.selectByExample(example);
            if (marketUsers != null && marketUsers.size() == 1) {
                MarketUser marketUser = marketUsers.get(0);
                String credentials = marketUser.getPassword(); //正确密码
                return new SimpleAuthenticationInfo(marketUser, credentials, this.getName());
            }
        }

        return null;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 获得principal信息 → 根据principal信息获得对应的权限信息
        // 上面的doGetAuthorizationInfo中的第一个参数
        MarketAdmin primaryPrincipal = (MarketAdmin) principalCollection.getPrimaryPrincipal();

        // 根据marketAdmin查询它对应的权限
        // 拿到用户信息，可以获得role角色信息，根据角色信息，拿到权限信息
        Integer id = primaryPrincipal.getId();
        List<String> permissionsByAdminId = getPermissionsByAdminId(id);

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addStringPermissions(permissionsByAdminId);
        return simpleAuthorizationInfo;
    }

    public List<String> getPermissionsByAdminId(Integer id) {
        // 应该来源于数据库
        MarketAdmin marketAdmin = adminMapper.selectByPrimaryKey(id);
        Integer[] roleIds = marketAdmin.getRoleIds();
        List<String> list = marketPermissionMapper.selectPermissionByIds(roleIds);
        return list;
    }
}
